<?php
/**
 * @Author: Ron Chen
 * @Date:   2017-01-15 21:59:27
 * @Last Modified by:   Ron Chen
 * @Last Modified time: 2017-05-15 23:00:50
 */

namespace backend\controllers;

use common\models\BaseModels;
use yii\data\ActiveDataProvider;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\helpers\ArrayHelper;

interface IExtend {
    function settings();
}

/**
 * 基本的控制类
 */
class BaseExtendController extends BaseController implements IExtend{
	public  $settings;
    
    const IS_VALID_ONE  = 1;
    const IS_VALID_ZERO = 0;

	const PAGE_ONE = 1;
	const PAGE_MAX = 20;

    const HOOK_BEFORE_FILTER = 'hook_before_filter';

    const HOOK_BEFORE_INDEX = "hook_before_index";
    const HOOK_AFTER_INDEX  = "hook_after_index";
    const HOOK_BEFORE_VIEW  = "hook_before_view";
    const HOOK_AFTER_VIEW    = "hook_after_view";

    const HOOK_BEFORE_CREATE = "hook_before_create";
    const HOOK_AFTER_CREATE  = "hook_after_create";
    const HOOK_BEFORE_CREATE_POST = "hook_before_create_post";
    const HOOK_AFTER_CREATE_POST  = "hook_after_create_post";

    const HOOK_AFTER_FORM    = "hook_after_form";

    const HOOK_BEFORE_UPDATE = "hook_before_update";
    const HOOK_AFTER_UPDATE  = "hook_after_update";
    const HOOK_BEFORE_SAVE   = 'hook_before_save';
    const HOOK_AFTER_SAVE    = 'hook_after_save';

    const HOOK_BEFORE_DELETE = "hook_before_delete";
    const HOOK_AFTER_DELETE  = "hook_after_delete";
    const HOOK_BEFORE_RESET  = "hook_before_reset";
    const HOOK_AFTER_RESET   = "hook_after_reset";

    const HOOK_FIND_MODEL    = "hook_find_model";
    
	public function init(){
        $this->settings = $this->settings();
    }

    /**
	 * 设置控制器的数据模型
	 */
	public function settings() {
        return [];
    }

    /**
     * 筛选条件
     * @return 返回数组
     */
    private function getFilter(){
        $param = [];
        if (method_exists($this, self::HOOK_BEFORE_FILTER)) {
            $param = call_user_func(array($this, self::HOOK_BEFORE_FILTER));
        }
        if (!$param) {
            $param = ["1=1"];    
        }
        
        return $param;
    }

    /**
     * 获取模型列表
     * @return mixed
     */
    public function actionIndex()
    {
    	$model = $this->settings['model'];

        //@notice : 必选
        $param = $this->getFilter();
        
        if (method_exists($this, self::HOOK_BEFORE_INDEX)) {
            $query = call_user_func(array($this, self::HOOK_BEFORE_INDEX));
        }
        $param = isset($query["param"]) ? $query["param"] : $param;
        $page  = isset($query["page"])  ? $query["page"]  : self::PAGE_ONE;
        $size  = isset($query["size"])  ? $query["size"]  : self::PAGE_MAX;
            
        $order_desc = sprintf(" %s desc",$this->settings['pk']);
        if(empty($this->where)) {
            if ($param) {
                $query = $model::find()->where(join(" AND ", $param))->orderBy($order_desc);
            } else {
                $query = $model::find()->orderBy($order_desc);
            }
        }else{
            if ($param) {
                $query = $model::find()->where(join(" AND ", $param))->andWhere(join(" AND ", $this->where))->orderBy($order_desc);
            } else {
                $query = $model::find()->where(join(" AND ", $this->where))->orderBy($order_desc);
            }
        }

        $dataProvider = new ActiveDataProvider([
            'query' => $query,
            'pagination' => [
                'pageSize' => $size,
            ],
        ]);

        $data["dataProvider"] = $dataProvider;

        if (method_exists($this, self::HOOK_AFTER_INDEX)) {
            $res = call_user_func(array($this, self::HOOK_AFTER_INDEX),$model);
            $data = ArrayHelper::merge($data,$res);
        }

        return $this->render('index', $data );
    }

    /**
     * 查看模型单条信息
     * @param $id 主键 ID
     * @return mixed
     */
    public function actionView($id)
    {
        $model = $this->findModel($id);
        if (method_exists($this, self::HOOK_AFTER_VIEW)) {
            $model = call_user_func(array($this, self::HOOK_AFTER_VIEW),$model);
        }
        return $this->render('view', [
            'model' => $model
        ]);
    }

    /**
     * 添加单个模型数据
     * @return mixed
     */
    public function actionCreate()
    {
        $model = $this->settings['model'];
        if (method_exists($this, self::HOOK_BEFORE_CREATE)) {
            $model = call_user_func(array($this, self::HOOK_BEFORE_CREATE),$model);
        }
        if ($model->load($this->request->post()) && $model->validate()) {
            if (method_exists($this, self::HOOK_BEFORE_CREATE_POST)) {
                $model = call_user_func(array($this, self::HOOK_BEFORE_CREATE_POST),$model);
            }
            $this->setSuccess('保存成功');

            $model->save();
            return $this->redirect(['view', 'id' => $model->id]);
        } else {
            $errors = $model->getErrors();
            if (!empty($errors)) {
                $this->setError($this->getErrorText($errors));
            }
            $data = ['model' => $model];
            if (method_exists($this, self::HOOK_AFTER_FORM)) {
                $res  = call_user_func(array($this, self::HOOK_AFTER_FORM),$model);
                $data = ArrayHelper::merge($data,$res);
            }
            return $this->render('create', $data);
        }
    }

    /**
     * 更新单个模型数据
     * @param integer $id
     * @return mixed
     */
    public function actionUpdate($id)
    {
        $model = $this->findModel($id);
        if (method_exists($this, self::HOOK_BEFORE_UPDATE)) {
            $model  = call_user_func(array($this, self::HOOK_BEFORE_UPDATE),$model);
        }
        if ($model->load($this->request->post()) && $model->validate()) {
            if (method_exists($this, self::HOOK_BEFORE_SAVE)) {
                $model  = call_user_func(array($this, self::HOOK_BEFORE_SAVE),$model);
            }
            if($model->save()){
                return $this->redirect(['view', 'id' => $model->id]);    
            }
        } else {
            $errors = $model->getErrors();
            if (!empty($errors)) {
                $this->setError($this->getErrorText($errors));
            }
            $data = ['model' => $model];
            if (method_exists($this, self::HOOK_AFTER_FORM)) {
                $res  = call_user_func(array($this, self::HOOK_AFTER_FORM),$model);
                $data = ArrayHelper::merge($data,$res);
            }
            return $this->render('update', $data);
        }
    }

   

    /**
     * 删除模型数据
     * @param integer $id
     * @return mixed
     */
    public function actionDelete($id)
    {
        $model = $this->findModel($id);
        if (method_exists($this, self::HOOK_BEFORE_DELETE)) {
            $model = call_user_func(array($this, self::HOOK_BEFORE_DELETE),$model);
        }

        if ($model->is_valid) {
            $model->is_valid = self::IS_VALID_ZERO;
        }

        $model->save();

        return $this->redirect(['index']);

        if (method_exists($this, self::HOOK_AFTER_DELETE)) {
            return call_user_func(array($this, self::HOOK_AFTER_DELETE),$model);
        }else{
            return $this->redirect(['index']);
        }
    }

    /**
     * 恢复数据
     */
    public function actionReset($id){
        $model = $this->findModel($id);
        if (method_exists($this, self::HOOK_BEFORE_RESET)) {
            $model = call_user_func(array($this, self::HOOK_BEFORE_RESET),$model);
        }
        
        if ($model->is_valid == self::IS_VALID_ZERO) {
            $model->is_valid = self::IS_VALID_ONE ;
        }
        
        if (method_exists($this, self::HOOK_AFTER_RESET)) {
            return call_user_func(array($this, self::HOOK_AFTER_RESET),$model);
        }else{
            return $this->redirect(['index']); 
        }
    }

    /**
     * 获取单个模型数据
     */
    protected function findModel($id)
    {
    	$model = $this->settings['model'];
        if (($model = $model::findOne($id)) !== null) {
            if (method_exists($this, self::HOOK_FIND_MODEL)) {
                $model = call_user_func(array($this, self::HOOK_FIND_MODEL),$model);
            }
            return $model;
        } else {
            throw new NotFoundHttpException('The requested page does not exist.');
        }
    }
}
